package OS

import (
	"net"
	"os/exec"
	"regexp"
	"runtime"
	"strings"
)

type hardware struct {
	CPUID        string
	MAC          string
	SerialNumber string
	ARCH         string
}

func (e *hardware) init() {
	// 获得CPUID
	e.CPUID, _ = e.GetCPUID()
	if e.CPUID != "" {
		e.CPUID = strings.ToUpper(e.CPUID)
	}

	// 获得CPUID
	e.ARCH = runtime.GOARCH

	// 获得MAC地址
	e.MAC, _ = e.GetMac()
	if e.MAC != "" {
		e.MAC = strings.ToUpper(e.MAC)
	}

	// 如果没有CPUID那么用MAC地址作为设备的序列号
	if e.CPUID != "" {
		e.SerialNumber = e.CPUID
	} else {
		e.SerialNumber = strings.ReplaceAll(e.MAC, ":", "")
	}
}

func (e *hardware) GetCPUID() (string, error) {
	if Type.IsWindows() {
		return e.getWindowsCPUID()
	}
	if Type.IsLinux() {
		return e.getLinuxCPUID()
	}

	return "", nil
}

func (e *hardware) GetMac() (string, error) {
	if Type.IsWindows() {
		return e.getWindowsMac()
	}
	if Type.IsLinux() {
		return e.getLinuxMac()
	}

	return "", nil
}

func (e *hardware) getWindowsMac() (string, error) {
	// 获取本机的MAC地址
	interfaces, err := net.Interfaces()
	if err != nil {
		return "", err
	}
	inter := interfaces[0]
	mac := inter.HardwareAddr.String()
	return mac, nil
}

func (e *hardware) getWindowsCPUID() (string, error) {
	cmd := exec.Command("wmic", "cpu", "get", "ProcessorID")
	out, err := cmd.CombinedOutput()
	if err != nil {
		return "", err
	}

	str := string(out)

	//匹配一个或多个空白符的正则表达式
	reg := regexp.MustCompile("\\s+")
	str = reg.ReplaceAllString(str, "")
	return str[len("ProcessorID"):], nil
}

func (e *hardware) getLinuxCPUID() (string, error) {
	cmd := exec.Command("/bin/sh", "-c", "cat /proc/cpuinfo  | grep Serial |awk -F': ' '{print $2}'")
	str, err := Shell.ExecShell(cmd)
	if err != nil {
		return "", err
	}

	str = strings.ReplaceAll(str, "\r", "")
	str = strings.ReplaceAll(str, "\n", "")
	str = strings.ToUpper(str)
	return str, nil
}

func (e *hardware) getLinuxMac() (string, error) {
	cmd := exec.Command("/bin/sh", "-c", "ifconfig | awk '/ether/ {print $2}'")
	str, err := Shell.ExecShell(cmd)
	if err != nil {
		return "", err
	}

	ifs := strings.Split(str, "\n")
	if len(ifs) == 0 {
		return "", nil
	}

	str = ifs[0]
	str = strings.ReplaceAll(str, ":", "")
	str = strings.ToUpper(str)
	return str, nil
}
